package com.ruoyi.web.controller.core.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ruoyi.comm.crud.bean.dto.CheckDataDTO;
import com.ruoyi.comm.crud.bean.dto.CheckUserDTO;
import com.ruoyi.comm.crud.bean.dto.InsertUserDTO;
import com.ruoyi.comm.crud.bean.dto.UpdateUserDTO;
import com.ruoyi.comm.crud.service.IBaseService;
import com.ruoyi.common.core.controller.PrefixController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageQO;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.ClzUtils;
import com.ruoyi.common.utils.bean.BeanCopier;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.interceptor.anno.MyPermissions;
import com.ruoyi.web.controller.core.IBaseCtroller;

/**
 * BaseControllerImpls
 * 
 * @author riverbo
 * @date 2024-05-06
 */
public class BaseCtrollerImpls<M extends IBaseService<T>, T> extends PrefixController implements IBaseCtroller<T> {

//    protected final Class<?>[] typeArguments = GenericTypeUtils.resolveTypeArguments(getClass(), ServiceImpl.class);
	
	protected final Class<T> entityClass = currentModelClass();

	@Autowired
	protected M baseService;
	public InsertUserDTO getInsertDTO() {
		InsertUserDTO dto = new InsertUserDTO();
		//
		SysUser user = getSysUser();
		dto.setCreateBy(user.getLoginName());
		dto.setCreateUserId(user.getUserId());
		dto.setCreateTime(new Date());
		return dto;
	}

	public UpdateUserDTO getUpdateDTO() {
		UpdateUserDTO dto = new UpdateUserDTO();
		//
		SysUser user = getSysUser();
		dto.setUpdateBy(user.getLoginName());
		dto.setUpdateUserId(user.getUserId());
		dto.setUpdateTime(new Date());
		return dto;
	}

	public CheckUserDTO getCheckDTO() {
		CheckUserDTO dto = new CheckUserDTO();
		//
		SysUser user = getSysUser();
		dto.setCheckBy(user.getLoginName());
		dto.setCheckUserId(user.getUserId());
		dto.setCheckTime(new Date());
		return dto;
	}
	
	public void cloneInsertUser(Object obj) {
		InsertUserDTO dto = getInsertDTO();
		BeanCopier.copyProperties(dto, obj);
	}
	
	public void cloneUpdateUser(Object obj) {
		UpdateUserDTO dto = getUpdateDTO();
		BeanCopier.copyProperties(dto, obj);
	}
	
	public void cloneCheckUser(Object obj) {
		CheckUserDTO dto = getCheckDTO();
		BeanCopier.copyProperties(dto, obj);
	}

	//@Override
	public IBaseService<T> getBaseService() {
		return baseService;
	}

	//@Override
	public Class<T> getEntityClass() {
		return entityClass;
	}

	@SuppressWarnings("unchecked")
	protected Class<T> currentModelClass() {
		// return (Class<T>) this.typeArguments[1];
		return ClzUtils.getSuperClassGenericType(getClass(), 1);
	}

//	@Override
//	public String prefix {
//		if (prefix == null) {
//			RequestMapping annotation = this.getClass().getAnnotation(RequestMapping.class);  
//			System.out.println(annotation.value());
//			synchronized (prefix) {
//				prefix = annotation.value()[0];
//			}
//			return prefix;
//		} else {
//			return prefix;
//		}
//	}

	// @RequiresPermissions("biz:casetype:query")
	@MyPermissions("查询")
	@Override
	@GetMapping({ "", "/", "index", "query" })
	public String query() throws Exception {
		String url = prefix + "/query";
		tryPermitted(url);
		return url;
	}

	@MyPermissions("选择")
	@Override
	@GetMapping({ "choice" })
	public String choice() throws Exception {
		String url = prefix + "/choice";
		tryPermitted(url);
		return url;
	}

	/**
	 * 查询 T t 列表
	 */
	// @RequiresPermissions("biz:casetype:list")
	@MyPermissions("查询")
	@Override
	@PostMapping("/list")
	@ResponseBody
	public TableDataInfo list(T t) throws Exception {
		String url = this.prefix + "/list";
		tryPermitted(url);
		startPage();
		List<T> list = baseService.selectList(t);
		return getDataTable(list);
	}
	
	// @RequiresPermissions("biz:casetype:query")
	@Override
	@MyPermissions("查询")
	@PostMapping("/query")
	@ResponseBody
	public TableDataInfo query(T t, PageQO page) throws Exception {
		String url = this.prefix + "/query";
		tryPermitted(url);
		List<T> list = baseService.query(t, page);
		return getDataTable(list);
	}

	/**
	 * 导出 T t 列表
	 */
	//@RequiresPermissions("biz:casetype:export")
	@MyPermissions("导出")
	// @Log(title = "casetype", businessType = BusinessType.EXPORT)
	@Override
	@PostMapping("/export")
	@ResponseBody
	public AjaxResult export(T t) throws Exception {
		String url = this.prefix + "/export";
		tryPermitted(url);
		List<T> list = baseService.selectList(t);
		ExcelUtil<T> util = new ExcelUtil<T>(entityClass);
		return util.exportExcel(list, "export");
	}

	/**
	 * 新增 T t
	 */
//	@MyPermissions("新增")
//	@Override
//	@GetMapping("/add")
//	public String add() throws Exception {
//		String url = prefix + "/add";
//		tryPermitted(url);
//		return url;
//	}
	
	@MyPermissions("新增")
	@Override
	@GetMapping("/add")
	public String add(ModelMap mmap) throws Exception {
		String url = prefix + "/add";
		tryPermitted(url);
		return url;
	}

	/**
	 * checkNameUnique
	 */
	@Override
	@PostMapping("/checkNameUnique")
	@ResponseBody
	public Boolean checkNameUnique(T t) throws Exception {
		return baseService.checkNameUnique(t);
	}
	
//	public T checkNameUnique(String name) {
//		return baseService.checkNameUnique(name);
//	}

//	@Override
//	@PostMapping("/checkIdNameUnique")
//	@ResponseBody
//	public Long checkIdNameUnique(T t) {
//		return baseService.checkIdNameUnique(t);
//	}

//	@Override
//	@PostMapping("/existsIdNameUnique")
//	@ResponseBody
//	public Boolean existsIdNameUnique(T t) {
//		return baseService.existsIdNameUnique(t);
//	}

	/**
	 * 新增保存 T t
	 */
	// @RequiresPermissions("biz:casetype:add")
	@MyPermissions("新增")
	// @Log(title = "casetype", businessType = BusinessType.INSERT)
	@PostMapping("/add")
	@ResponseBody
	public AjaxResult addSave(@Validated T t) throws Exception {
		String url = prefix + "/add";
		tryPermitted(url);
		int n = baseService.insert(t);
		return toAjax(n);
	}

	/**
	 * 打开修改页面 id
	 */
	@MyPermissions("修改")
	@GetMapping("/edit/{id}")
	public String edit(@PathVariable("id") Long id, ModelMap mmap) throws Exception {
		String url = prefix + "/edit";
		tryPermitted(url);
		T t = baseService.selectById(id);
		mmap.put("vo", t);
		return url;
	}

	/**
	 * 修改保存 T t
	 */
	@MyPermissions("修改")
	// @RequiresPermissions("biz:casetype:edit")
	// @Log(title = "casetype", businessType = BusinessType.UPDATE)
	@PostMapping("/edit")
	@ResponseBody
	public AjaxResult editSave(@Validated T t) throws Exception {
		String url = prefix + "/edit";
		tryPermitted(url);
		int n = baseService.update(t);
		return toAjax(n);
	}

	/**
	 * 删除 T t
	 */
	// @RequiresPermissions("biz:casetype:remove")
	@MyPermissions("删除")
	// @Log(title = "casetype", businessType = BusinessType.DELETE)
	@PostMapping("/remove")
	@ResponseBody
	public AjaxResult remove(String ids) throws Exception {
		String url = prefix + "/remove";
		tryPermitted(url);
		int n = baseService.deleteByIds(ids);
		return toAjax(n);
	}
	
	@MyPermissions("审批")
	// @RequiresPermissions("biz:casetype:edit")
	// @Log(title = "casetype", businessType = BusinessType.UPDATE)
	@PostMapping("/check")
	@ResponseBody
	public AjaxResult check(String ids) throws Exception {
		String url = prefix + "/check";
		tryPermitted(url);
		CheckDataDTO data = BeanCopier.copyProperties(getCheckDTO(), CheckDataDTO.class);
		data.setIds(Convert.toLongArray(ids));
		int n = baseService.checkByIds(data);
		return toAjax(n);
	}

//	@MyPermissions("审批")
//	// @RequiresPermissions("biz:casetype:edit")
//	// @Log(title = "casetype", businessType = BusinessType.UPDATE)
//	@PostMapping("/check")
//	@ResponseBody
//	public AjaxResult check(@Validated T t) throws Exception {
//		String url = prefix + "/check";
//		tryPermitted(url);
//		cloneCheckUser(t);
//		int n = baseService.check(t);
//		return toAjax(n);
//	}

}